第 3 步 - 加载地区并实例化预设件

在本步骤中,使用 Kanzi Engine API 加载应用程序中地区的地区包,并在用户点击 Kanzi 应用程序中的地区按钮时实例化包含从左向右和从右向左书写的按钮和布局的预设件。

加载地区包

在本节中,您将学习使用 Kanzi Engine API 加载应用程序中地区的地区包。使用 API 为选定的地区正确地实例化有正确布局的 IVI GridLocaleButton 预设件。

要加载地区包:

  1. 在 Windows 资源管理器的 <ProjectName>/Application/bin/Locale_packs 目录中,在文本编辑器中打开 binaries.cfg 文件并向文件添加包含这些地区的地区包的ArabicHebrew kzb 文件。每行只添加一个 kzb 文件的名称。
    binaries.cfg 文件已包含JapaneseChineseKorean kzb 文件。
    ja-JP
    ko-KR
    zh-ZH
    ar-AR
    he-HE
  2. 在 Visual Studio 中,为您的应用程序打开位于 Application/configs/platforms/win32 的 Visual Studio 解决方案。

    如果您在 Visual Studio 2017 中打开教程解决方案,遇到提示您重新定位工程到最新的 Microsoft 工具集时,请点击取消 (Cancel)。

  3. 创建含有ArabicHebrew 地区的名称的集合。在添加地区时,应用程序会检查地区是否在从右向左书写地区集合中。
    localization.cpp 文件中,替换:
    class LocalizationApplication : public ExampleApplication
    {
        //在 Kanzi Studio 工程中定义的自定义属性类型的共享指针类型。
        typedef shared_ptr<DynamicPropertyType<string> > StringDynamicPropertyTypeSharedPtr;

    class LocalizationApplication : public ExampleApplication
    {
        //创建一个包含从右向左书写地区的名称的集合。
        set<string> m_rtlLocales;
  4. onProjectLoaded 函数中首先获取LocalesLocaleSelector 节点并将ArabicHebrew 地区添加到从右向左书写地区集合中。
    onProjectLoaded 函数的内容替换为:
        virtual void onProjectLoaded() KZ_OVERRIDE
        {
            //获取 IVI Grid 节点,以便向其添加消息过滤器。
            Node2DSharedPtr iviGrid = getRoot()->lookupNode<Node2D>("IVI Grid");
    
            //向 IVI Grid 节点添加消息过滤器来了解用户何时点击 LocaleSelector 节点中的地区按钮。
            iviGrid->addMessageFilter(ButtonConcept::ClickedMessage, bind(&LocalizationApplication::onLocaleButtonClicked, this, placeholders::_1));
    
            //向集合添加从右向左书写地区。使用集合确定哪个是从右向左书写地区并为选定的地区使用正确的 IVI Grid 布局
            //(所选地区)。
            m_rtlLocales.insert("ar-AR");
            m_rtlLocales.insert("he-HE");
        }
  5. 在您粘贴的前一个代码块中,在onProjectLoaded 函数中从地区包加载本地化资源:
            //设置存储地区包的目录的名称。
            const string localePacksDirectory = "Locale_packs";
    
            //读取包含 kzb 文件列表(其中包含地区包)的 binaries.cfg.file。
            string configFileName = localePacksDirectory + "/binaries.cfg";
            ReadOnlyDiskFile binariesConfigFile(configFileName);
            string binariesConfigContents = readAsText(binariesConfigFile);
            stringstream binariesConfigFileStream(binariesConfigContents);
    
            string localeId;
    
            //加载存储在每个地区包 kzb 文件中的本地化资源(kzb 文件存储在 binaries.cfg 文件中)。
            while (getline(binariesConfigFileStream, localeId))
            {
                //移除空白。
                trim(localeId);
    
                //创建 kzb 文件路径。
                string localizationKzbFilePath = "./"+ localePacksDirectory + "/" + localeId + ".kzb";
    
                //添加 kzb 文件到 Kanzi 资源管理器。
                ResourceManager* resourceManager = getResourceManager();
                resourceManager->addKzbFile(localizationKzbFilePath);
    
                //获取地区目录。
                string dictionaryUrl = "kzb://localization/Locales/" + localeId;
                ResourceDictionarySharedPtr localeDictionary = getResourceManager()->acquireResource<ResourceDictionary>(dictionaryUrl);
    
                //从地区的本地化表中的 LocaleDisplayName 资源 ID 中,获取您要在 UI 中显示的地区的名称。
                TextResourceSharedPtr localeDisplayName = localeDictionary->acquire<TextResource>(ResourceID("LocaleDisplayName"));
    
                //获取定位LocaleButton 2D 切换按钮 (Toggle button 2D) 节点的LocaleSelector 2D 堆栈布局 (Stack Layout 2D) 节点。
                StackLayout2DSharedPtr localeSelector = getRoot()->lookupNode<StackLayout2D>("./IVI Grid/IVI Grid LeftToRight/Locales/LocaleSelector");
    
                //检查地区是否在 rtlLocales 集合中。
                if (m_rtlLocales.count(localeId) > 0)
                {   
                    //获取 LocaleButton RightToLeft 预设件并建立按钮,然后将其添加到 LocaleSelector 节点。
                    Node2DSharedPtr localeButton = createLocaleButton("kzb://localization/Prefabs/LocaleButton RightToLeft", localeDictionary, localeDisplayName, localeId);
                    //将 LocaleButton 节点添加到 LocaleSelector 节点。
                    localeSelector->addChild(localeButton);
                }
                else
                {
                    //获取 LocaleButton LeftToRight 预设件并建立按钮,然后将其添加到 LocaleSelector 节点。
                    Node2DSharedPtr localeButton = createLocaleButton("kzb://localization/Prefabs/LocaleButton LeftToRight", localeDictionary, localeDisplayName, localeId);
                    //将 LocaleButton 节点添加到 LocaleSelector 节点。
                    localeSelector->addChild(localeButton);
                }
            }
  6. 定义 createLocaleButton 函数,返回从左向右或从右向左LocaleButton 预设件,取决于应用程序加载的是从左向右还是从右向左书写地区。在 onProjectLoaded 函数之后添加:
        Node2DSharedPtr createLocaleButton(string url, ResourceDictionarySharedPtr localeDictionary, TextResourceSharedPtr localeDisplayName, string localeId)
        {
            //获取并实例化 LocaleButton RightToLeft 预设件,用于设置从右向左书写地区的按钮。
            //您使用完整的 kzb 资源 URL 时,路径以 kzb:// 开头,后跟工程名称和资源位置。
            PrefabTemplateSharedPtr localeButtonPrefab = getResourceManager()->acquireResource<PrefabTemplate>(url);
            Node2DSharedPtr localeButton = localeButtonPrefab->instantiate<Node2D>("LocaleButton_" + localeId);
    
            //获取自定义属性类型以设置 LocaleButton 节点中的地区的名称。自定义属性类型在 Kanzi Studio 工程中定义。
            DynamicPropertyType<string> localeNameProperty("Localization.LocaleName");
            //获取自定义属性类型以设置应用程序中的地区。自定义属性类型在 Kanzi Studio 工程中定义。
            DynamicPropertyType<string> localeIdProperty("Localization.LocaleID");
    
            //使用 LocaleName 属性在 UI 中显示地区的名称。
            localeButton->setProperty(localeNameProperty, localeDisplayName->getText());
            //设置 LocaleID 属性。您在用户点击 LocaleButton 并用它将应用程序改为该地区时获取属性的值。
            localeButton->setProperty(localeIdProperty, localeId);
    
            //添加组内索引 (Index in Group) 属性,使Locales 2D 切换按钮组 (Toggle Button Group 2D) 节点自动设置切换按钮的索引。 
            localeButton->setProperty(ButtonConcept::IndexInGroupProperty, -1);
    
            //设置LocaleButton2D 文本块 (Text Block 2D) 节点的样式,使其设置LocaleDisplayName 地区的正确字体。
            //使用这种方法仅应用地区包中的样式而不改变应用程序中的地区。
            StyleSharedPtr style = localeDictionary->acquire<Style>(ResourceID("LocaleStyle"));
            localeButton->setStyle(style);
    
            return localeButton;
        }
  7. createLocaleButton 函数之后实现按钮的 onLocaleButtonClicked 事件处理程序,点击来自 LocaleButton 节点的消息。用户点击 LocaleButton 按钮时,事件处理程序移除现有布局,实例化并添加正确的 IVI Grid 节点布局,并设置应用程序的地区。
        void onLocaleButtonClicked(ButtonConcept::ClickedMessageArguments& messageArguments)
        {
            //获取自定义属性类型以设置应用程序中的地区。自定义属性类型在 Kanzi Studio 工程中定义。
            DynamicPropertyType<string> localeIdProperty("Localization.LocaleID");
    
            //从用户点击的按钮获取LocaleID 属性的值。
            string localeId = messageArguments.getSource()->getProperty(localeIdProperty);
    
            //检查选定地区是从右向左还是从左向右书写。
            bool rtl = m_rtlLocales.count(localeId) > 0;
            //将路径变量设为选定地区的 IVI Grid 布局中的 Locales 2D 切换按钮组 (Toggle Button Group 2D) 节点。
            string pathToNewParent = rtl ? "IVI Grid/IVI Grid RightToLeft/Locales" : "IVI Grid/IVI Grid LeftToRight/Locales";
    
            //存储现有的具有 LocaleButton 2D 切换按钮 (Toggle button 2D) 节点的 2D 堆栈布局 (Stack Layout 2D) 节点。
            StackLayout2DSharedPtr localeSelector = messageArguments.getSource()->lookupNode<StackLayout2D>("..");
    
            //移除树结构中的现有地区选择器节点。
            Node2DSharedPtr oldLocaleSelectorParent = localeSelector->lookupNode<Node2D>("..");
            oldLocaleSelectorParent->removeChild(*localeSelector);
    
            //将应用程序的地区设为用户选择其按钮的地区。
            getScreen()->setLocale(localeId);
    
            //获取Locales 2D 切换按钮组 (Toggle Button Group 2D) 节点并向其添加LocaleSelector 2D 堆栈布局 (Stack Layout 2D) 节点。
            ToggleButtonGroup2DSharedPtr toggleButtonGroup = getRoot()->lookupNode<ToggleButtonGroup2D>(pathToNewParent);
            toggleButtonGroup->addChild(localeSelector);
        }
  8. 在 Visual Studio 中,为您的 Visual Studio 版本选择一个解决方案配置并运行应用程序。
    例如,如果您仍在开发应用程序,选择GL_vs2015_Debug 配置。要创建 Kanzi 应用程序的产品版本,选择一个可用的发布配置。
  9. 在应用程序中,当您点击ArabicHebrew 地区时,应用程序将地区的正确布局实例化。


< 上一步

接下来该做什么?

在本教程中,您学习了如何为从右向左书写地区准备已本地化的 Kanzi 应用程序以及如何使用 Kanzi Engine API 实例化设置从左向右和从右向左书写地区布局的预设件。现在您可以:

另请参阅

要详细了解有关如何本地化您的 Kanzi 应用程序的信息,请参阅本地化

要详细了解有关 kzb 文件的信息,请参阅使用 kzb 文件

要了解有关 Kanzi 如何处理资源的信息,请参阅资源管理

要详细了解有关如何使用资源字典的信息,请参阅资源

要详细了解有关如何使用应用程序中字体的信息,请参阅导入字体